package scene.shape.geometry;

import raytracing.HitRecord;
import raytracing.Ray;
import scene.shape.BoundingBox;
import util.Vector3f;

public class Plane extends Primitive{
	
	private Vector3f p;
	private Vector3f n;

	public Plane(Vector3f a, Vector3f n){
		this.p = a;
		this.n = n.normalize();
	}
	
	public HitRecord intersects(Ray ray, float mint, float maxt) {
		Vector3f u = ray.getDirection(), w = ray.getE().subtract(p);
		if(Math.abs(n.dot(u)) < 0.0001f){
			//parallel, no intersection or the ray lies entirely in the plane, if so,
			//there is no intersection point defined so this case is useless in raytracing
			return HitRecord.NOHIT;
		}
		float t = - n.dot(w)  / n.dot(u); //n.(V0 - P0) / n.u
		if(t < mint || t > maxt)
			return HitRecord.NOHIT;
		return new HitRecord(true,t,ray, n, this);
	}
	
	public boolean isInPlane(Vector3f v){
		return (Math.abs(n.dot(v.subtract(p).normalize())) < 0.0001f);
	}

	@Override
	public BoundingBox getBoundingBox() {
		return new BoundingBox(new Vector3f(Float.NaN, Float.NaN, Float.NaN), new Vector3f(Float.NaN, Float.NaN, Float.NaN));
	}

	@Override
	public float getU(HitRecord hr) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public float getV(HitRecord hr) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public HitRecord hit(Ray r, float mint, float maxt) {
		return intersects(r, mint, maxt);
	}
	
	public float implicit(Vector3f p){
		return n.dot(p.subtract(this.p));
	}
	
	

}
